package com.rtsapp.server.benchmark.script;

import com.rtsapp.server.common.ByteBuffer;
import com.rtsapp.server.utils.logger.BinRollingLogger;
import com.rtsapp.server.utils.logger.LoggerThread;
import com.rtsapp.server.network.protocol.command.ICommand;
import com.rtsapp.server.utils.logger.RollingCalendar;

/**
 * 脚本记录工具
 */
public class ScriptRecord {

    private static final int DEFAULT_COMMAND_LOG_BUFFER_SIZE = 2048;

    private static ScriptRecord instance = new ScriptRecord();

    public static ScriptRecord getInstance(){
        return instance;
    }

    private final ThreadLocal<ByteBuffer> bufferHolder = new ThreadLocal<>();

    private volatile LoggerThread loggerThread = null;

    private ScriptRecord( ){

    }

    /**
     * 停止脚本记录
     */
    public void stop(){
        if( loggerThread != null ){
            loggerThread.shutdown();
        }
    }


    /**
     * 记录日志
     * @param type 请求还是响应
     * @param userId
     * @param command
     */
    public void record( ScriptCommand.CommandType type,  int userId,  ICommand command ){

        ByteBuffer buffer = getBufferInThread( );

        ScriptCommand.writeCommand(type, userId, command, buffer);

        getLoggerThread().appendLog(buffer.toBytes());
    }




    private ByteBuffer getBufferInThread( ){

        ByteBuffer buffer =  bufferHolder.get();
        if( buffer == null ){
            buffer = new ByteBuffer( DEFAULT_COMMAND_LOG_BUFFER_SIZE );
            bufferHolder.set( buffer );
        }

        // 记得使用前重置
        buffer.reset();

        return buffer;
    }

    private LoggerThread getLoggerThread(){

        if( loggerThread == null ) {
            synchronized (this) {
                if (loggerThread == null) {

                    String dateFromat = "yyyy-MM-dd";
                    RollingCalendar calendar = new RollingCalendar();
                    calendar.setType(RollingCalendar.TOP_OF_DAY, 0);
                    BinRollingLogger logger = new BinRollingLogger("logs/commands-%s.log", dateFromat, calendar);

                    loggerThread = new LoggerThread(logger);

                    // 启动线程
                    Thread t = new Thread( loggerThread , "ScriptRecordThread" );
                    t.start();
                }
            }
        }

        return loggerThread;
    }




}
